import socket
import threading
import datetime
import sys
import logging
import time

FORMAT = "%(lineno)d %(threadName)s %(message)s"
logging.basicConfig(format=FORMAT, level=logging.DEBUG)


class Client:
    S_CHAR = '&#&#&'
    ENCODING = 'GBK'
    STR = S_CHAR.join(["{}"] * 6)
    SHOW_PEOPLE = 'show_people'
    REGISTER = 'register'
    LOGIN = 'login'

    def __init__(self, rip: str = '127.0.0.1', rport: int = 60000):
        self.raddr = rip, rport
        self.sock = socket.socket()
        try:
            self.sock.connect(self.raddr)
        except Exception as e:
            # 需要输出到日志，此处简单略过
            logging.info(f'服务器连接失败。异常是{e}')
            sys.exit(0)
        # 打印一句
        # 连接到服务器
        logging.info('成功连接至服务器')
        self.method = None
        self.data = None
        self.uuid = None
        self.password = None
        self.name = None
        self.ok = None
        threading.Thread(target=self._recv, name='recv', daemon=True).start()
        self.FORMAT = {
            'name': self.name,
            'uuid': self.uuid,
            'data': self.data,
            'method': self.method,
            'password': self.password,
            'ok': self.ok
        }
        logging.info('成功开启监听消息线程')

    def send_data(self, msg: str):
        self.switch(self.uuid)
        logging.info(f"the msg {msg}")
        self.data = msg
        self.sock.send(self.STR.format(*self.FORMAT.values()).encode(self.ENCODING))
        logging.info('成功发送')

    def switch(self, uid):
        self.uuid = uid

    def _recv(self):
        while True:
            name, uuid, data, method, password, ok = self.sock.recv(1024).decode(self.ENCODING).split(self.S_CHAR)
            logging.info('{}-{}-{}-{}-{}-{}'.format(name, uuid, data, method, password, ok))
            if method == self.REGISTER:
                self.uuid = data
                logging.info('{}-{}-{}-{}-{}-{}'.format(name, uuid, data, method, password, ok))
            elif method == self.LOGIN:
                self.FORMAT['ok'] = ok
                logging.info('{}-{}-{}-{}-{}-{}'.format(name, uuid, data, method, password, ok))
            elif method == self.SHOW_PEOPLE:
                logging.info('{}-{}-{}-{}-{}-{}'.format(name, uuid, data, method, password, ok))

    def show_people(self):
        # 以后方法多了可以定义为类常量
        logging.info('client show')
        self.FORMAT['method'] = self.SHOW_PEOPLE
        print(*self.FORMAT)
        self.sock.send(self.STR.format(*self.FORMAT.values()).encode(self.ENCODING))
        logging.info('+++++++++++++++++++++++++++++++++++')
        self.FORMAT['method'] = None

    def add_friend(self, uid: int, name: str = None):
        pass

    def del_friend(self, uid):
        pass

    def login(self):
        while True:
            self.FORMAT['uuid'] = input('your id').strip()
            self.FORMAT['password'] = input("password")
            self.FORMAT['method'] = self.LOGIN
            self.sock.send(self.STR.format(*self.FORMAT.values()).encode(self.ENCODING))
            time.sleep(0.5)
            if self.ok:
                logging.info('login~~~~~OK')
                break

    def add_group(self, gid, name: str = None):
        pass

    def logout_group(self, gid):
        pass

    def create_group(self):
        pass

    def judge(self, name):
        self.data = name
        self.sock.send(self.STR.format(*self.FORMAT.values()).encode(self.ENCODING))

    def reg_password(self, name, password):
        self.FORMAT['password'] = password
        self.FORMAT['name'] = name
        self.FORMAT['method'] = self.REGISTER
        self.sock.send(self.STR.format(*self.FORMAT.values()).encode(self.ENCODING))

    def register(self):
        while True:
            name = input("请输入用户名").strip()
            # 可以留着判断是否允许昵称相同
            # self.judge(name)
            password = input("请输入你的密码")
            self.reg_password(name, password)
            logging.info(f"your id is {self.uuid}")
            break


if __name__ == '__main__':
    c = Client()
    while True:
        cmd = input("""
        1 ---->register
        2 ---->login
        """).strip()
        if cmd == '1':
            c.register()
        else:
            c.login()
            break

    while True:
        print("""
        cmd   list
        q \t---->quit
        s \t---->show person
        id ID \t ---->chat with ID
        """)
        cmd = input('>>>').strip()
        print('your CMD is', cmd)
        if not cmd:
            continue
        elif cmd == 'q':  # OK
            logging.info(c.sock)
            c.sock.send(b'q')
            c.sock.close()
            logging.info(c.sock)
            break
        elif cmd == 's':
            logging.info('循环中')
            c.show_people()
        elif cmd.split()[0] == 'id':
            c.switch(cmd.split()[1])
            logging.info("切换聊天对象成功")
            msg = input("input>>>")
            c.send_data(msg)
        else:
            logging.info('else 子句')
            c.send_data(cmd)

logging.info('===end===')
